//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Policy Injection Application Block
//===============================================================================

using System;
using Microsoft.Practices.EnterpriseLibrary.Configuration.Design;
using Microsoft.Practices.EnterpriseLibrary.PolicyInjection.Configuration.Design;
using Microsoft.Practices.EnterpriseLibrary.PolicyInjection.Configuration.Design.MatchingRules;
using Microsoft.Practices.EnterpriseLibrary.PolicyInjection.Configuration;
using EntLibContrib.PolicyInjection.Configuration.Design.MatchingRules;

namespace EntLibContrib.PolicyInjection.Configuration.Design
{
	/// <summary>
	/// Policy Injection Node Builder
	/// </summary>
	public class PolicyInjectionNodeBuilder : NodeBuilder
	{
		#region Construction
		/// <summary>
		/// Initializes a new instance of the <see cref="PolicyInjectionNodeBuilder"/> class.
		/// </summary>
		/// <param name="serviceProvider">The a mechanism for retrieving a service object; that is, an object that provides custom support to other objects.</param>
		public PolicyInjectionNodeBuilder(IServiceProvider serviceProvider)
			: base(serviceProvider)
		{
		}
		#endregion

		#region Public Methods
		/// <summary>
		/// Builds the additional matching rule nodes.
		/// </summary>
		/// <param name="matchingRuleNode">The matching rule node.</param>
		public void BuildAdditionalMatchingRuleNodes(ConfigurationNode matchingRuleNode)
		{
			foreach (ConfigurationNode childMatchingRuleNode in matchingRuleNode.Nodes)
			{
				ICompositeMatchingRuleNode compositeRule = childMatchingRuleNode as ICompositeMatchingRuleNode;
				if (compositeRule != null)
				{
					BuildComposite(compositeRule);
				}
			}
		}
		#endregion

		#region Private Methods
		private void BuildComposite(ICompositeMatchingRuleNode compositeRule)
		{
			foreach (MatchingRuleData containedRuleData in compositeRule.ChildRules)
			{
				ConfigurationNode ruleNode = NodeCreationService.CreateNodeByDataType(containedRuleData.GetType(), new object[] { containedRuleData });
				((ConfigurationNode)compositeRule).AddNode(ruleNode);

				ICompositeMatchingRuleNode compositeChildRule = ruleNode as ICompositeMatchingRuleNode;
				if (compositeChildRule != null)
				{
					BuildComposite(compositeChildRule);
				}
			}
		}
		#endregion
	}
}
